package com.dhcc.bpm.modules.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dhcc.bpm.common.utils.CreateInsert;
import com.dhcc.bpm.common.utils.StringUtils;
import com.dhcc.bpm.common.utils.ZipUtils;
import com.dhcc.bpm.modules.api.service.IApiService;
import com.dhcc.bpm.modules.api.service.IBaseProductService;
import com.dhcc.bpm.modules.api.service.ISysService;
import com.dhcc.bpm.modules.api.vo.ApiVO;
import com.dhcc.bpm.modules.api.vo.BaseProductVO;
import com.dhcc.bpm.modules.api.vo.SysVO;
import com.dhcc.bpm.modules.system.entity.ExpSeq;
import com.dhcc.bpm.modules.system.entity.ExpSeqEntity;
import com.dhcc.bpm.modules.system.mapper.ExpSeqMapper;
import com.dhcc.bpm.modules.system.service.IExpSeqService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @version V1.0
 * @ClassName ExpSeqServiceImpl
 * @Description TODO
 * @Author xiafayu
 * @Date 2020/12/29 9:43
 * @Copyright: 2020 东华软件 .. All rights reserved.
 */
@Service
public class ExpSeqServiceImpl extends ServiceImpl<ExpSeqMapper, ExpSeq> implements IExpSeqService {

    private static final Logger log = LoggerFactory.getLogger(ExpSeqServiceImpl.class);

    @Value("${bpm.expTableList}")
    private String expTableLis;
    @Value("${bpm.file-public-path}")
    private String baseFilePath;
    @Autowired
    CreateInsert createInsert;
    @Autowired
    private ISysService sysService;
    @Autowired
    private IApiService apiService;
    @Autowired
    private IBaseProductService baseProductService;

    @Override
    public IPage<ExpSeqEntity> getTableName(IPage<ExpSeqEntity> page) {
        return page.setRecords(baseMapper.getTableName(page));
    }

    @Override
    public IPage<ExpSeq> queryExpSeq(IPage<ExpSeq> page, String expSeq) {
        return page.setRecords(baseMapper.queryExpSeq(page, expSeq));
    }

    @Override
    public Integer batchInsert(List<String> sql) {
        return baseMapper.batchInsert(sql);
    }

    @Override
    public IPage<T> queryListByTableName(IPage<T> page, String tableName, String expSeq) {
        return baseMapper.queryListByTableName(page, tableName, expSeq);
    }

    @Override
    public R createTableInsertBySysIds(String sysIds, String searchValue, String downloadNumType, String exportFile) {
        String baseProductIds = "";
        if (StringUtils.isEmpty(sysIds)) {
            JSONObject object = JSONObject.parseObject(searchValue);

            Query query = new Query();
            query.setSize(9999);
            query.setCurrent(1);

            ObjectMapper objectMapper = new ObjectMapper();
            SysVO sys = objectMapper.convertValue(object, SysVO.class);

            IPage<SysVO> pages = sysService.selectSysPage(Condition.getPage(query), sys);
            List<SysVO> records = pages.getRecords();

            for (SysVO sysVO : records) {
                sysIds = sysIds + sysVO.getId() + ",";
                BaseProductVO baseProduct = new BaseProductVO();

                Query baseProductquery = new Query();
                baseProductquery.setSize(9999);
                baseProductquery.setCurrent(1);

                baseProduct.setOpcSysId(sysVO.getId());
                if (!StringUtils.isEmpty(object.getString("sysType"))) {
                    baseProduct.setBaseType(object.getInteger("sysType"));
                }

                IPage<BaseProductVO> baseProductpages = baseProductService.selectBProductList(Condition.getPage(baseProductquery), baseProduct);
                List<BaseProductVO> baseProductrecords = baseProductpages.getRecords();

                for (BaseProductVO baseProductVO : baseProductrecords) {
                    baseProductIds = baseProductIds + baseProductVO.getId() + ",";
                }
            }
            sysIds = sysIds.substring(0, sysIds.length() - 1);

        } else {
            JSONObject object = JSONObject.parseObject(searchValue);
            sysIds = sysIds.substring(0, sysIds.length() - 1);
            List<String> list = Arrays.asList(sysIds.split(","));
            for (String sysId : list) {
                BaseProductVO baseProduct = new BaseProductVO();
                Query baseProductquery = new Query();
                baseProductquery.setSize(9999);
                baseProductquery.setCurrent(1);

                baseProduct.setOpcSysId(Long.parseLong(sysIds));

                if (!StringUtils.isEmpty(object.getString("sysType"))) {
                    baseProduct.setBaseType(object.getInteger("sysType"));
                }
                IPage<BaseProductVO> baseProductpages = baseProductService.selectBProductList(Condition.getPage(baseProductquery), baseProduct);

                List<BaseProductVO> baseProductrecords = baseProductpages.getRecords();

                for (BaseProductVO baseProductVO : baseProductrecords) {
                    baseProductIds = baseProductIds + baseProductVO.getId() + ",";
                }
            }
        }


        return createInsert(baseProductIds, sysIds, downloadNumType, exportFile, "1");
    }

    @Override
    public R createTableInsertByProductIds(String productIds, String searchValue, String downloadNumType, String exportFile) {
        if (StringUtils.isEmpty(productIds)) {
            JSONObject object = JSONObject.parseObject(searchValue);

            Query query = new Query();
            query.setSize(9999);
            query.setCurrent(1);

            ObjectMapper objectMapper = new ObjectMapper();
            BaseProductVO baseProduct = objectMapper.convertValue(object, BaseProductVO.class);

            IPage<BaseProductVO> pages = baseProductService.selectBaseProductPage(Condition.getPage(query), baseProduct);

            for (BaseProductVO baseProductVO : pages.getRecords()) {
                productIds = productIds + baseProductVO.getId() + ",";
            }
        }
        productIds = productIds.substring(0, productIds.length() - 1);

        return createInsert(productIds, "", downloadNumType, exportFile, "2");
    }

    @Override
    public R createTableInsertByApiIds(String apiIds, String searchValue, String downloadNumType, String exportFile) {
        if (StringUtils.isEmpty(apiIds)) {
            JSONObject object = JSONObject.parseObject(searchValue);

            Query query = new Query();
            query.setSize(9999);
            query.setCurrent(1);

            ObjectMapper objectMapper = new ObjectMapper();
            ApiVO apiVO = objectMapper.convertValue(object, ApiVO.class);

            IPage<ApiVO> pages = apiService.listInfo(Condition.getPage(query), apiVO);

            for (ApiVO api : pages.getRecords()) {
                apiIds = apiIds + api.getId() + ",";
            }
        }
        apiIds = apiIds.substring(0, apiIds.length() - 1);

        return createInsert(apiIds, "", downloadNumType, exportFile, "3");
    }


    public R createInsert(String prdtIds, String sysIds, String downloadNumType, String exportFile, String type) {
        List<String> lists = Arrays.asList(expTableLis.split(","));
        List<String> tabList = new ArrayList<>();
        lists.forEach(str -> {
            if(str.contains("opc_")) {
                tabList.add(str.split("-")[0]);
            }
        });

        ArrayList fileList = new ArrayList();

        StringBuilder result = new StringBuilder();

        prdtIds = Arrays.asList(prdtIds.split(",")).stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));

        for (String tableNames : tabList) {
            try {
                JSONObject opc_exp_seq = queryInsert(type, sysIds, tableNames, prdtIds, downloadNumType);

                String sql = opc_exp_seq.getString("sql");
                fileList.addAll((ArrayList) opc_exp_seq.get("fileList"));
                if (!"".equals(sql)) {
                    result.append(sql);
                    result.append("\r\n");
                }
            } catch (Exception e) {
                log.error("生成INSERT SQL失败：{}", e);
                return R.fail("生成INSERT SQL失败");
            }
        }

        ZipUtils zipUtils = new ZipUtils();
        Long timeLong = new Date().getTime();
        JSONObject res = new JSONObject();
        res.put("sql", result.toString());
        if (fileList.size() > 0) {
            // 生成zip包
            if (baseFilePath.lastIndexOf("/") == baseFilePath.length() - 1) {
                //末尾是 "/"
                if ("0".equals(exportFile)) {
                    zipUtils.toZipByPath(fileList, baseFilePath + timeLong + ".zip", baseFilePath);
                }
                res.put("zip", baseFilePath + timeLong + ".zip");
            } else {
                if ("0".equals(exportFile)) {
                    zipUtils.toZipByPath(fileList, baseFilePath + "/" + timeLong + ".zip", baseFilePath);
                }
                res.put("zip", baseFilePath + "/" + timeLong + ".zip");
            }
        }
        return R.data(res);
    }

    public JSONObject queryInsert(String type, String sysIds, String tableNames, String prdtIds, String downloadNumType) {

        if ("1".equals(type)) {
            return createInsert.getInsertSqlbySysIds(tableNames, sysIds, prdtIds, downloadNumType);
        }

        if ("2".equals(type)) {
            return createInsert.getInsertSqlbyProductIds(tableNames, prdtIds, downloadNumType);
        }

        if ("3".equals(type)) {
            return createInsert.getInsertSqlbyApiId(tableNames, prdtIds, downloadNumType);
        }

        return createInsert.getInsertSqlbyProductIds(tableNames, prdtIds, downloadNumType);

    }
}
